package com.yx.framedemo.model.utils.net;

import android.content.Context;

import com.yx.framedemo.view.utils.log.LogUtil;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

/**
 * Creator:Yx
 * Time:2020/10/20 14:14
 * Description:支持HTTPS
 */
public class SSLUtils {

    //  获取这个SSLSocketFactory 信任所有证书
    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            if (getSSLContext() != null) {
                return getSSLContext().getSocketFactory();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     * 获取这个SSLSocketFactory  信任指定证书
     * 加入证书源文件，我的证书是放在res/Raw下面的myssl.cer：
     * context 上下文
     * certificates 是你raw下证书源ID，可多个, int[] certificates = {R.raw.myssl}
     */
    public static SSLSocketFactory getSSLSocketFactory(Context context, int[] certificates) {
        if (context == null) {
            throw new NullPointerException("context == null");
        }

        CertificateFactory certificateFactory;
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);

            for (int i = 0; i < certificates.length; i++) {
                InputStream certificate = context.getResources().openRawResource(certificates[i]);
                keyStore.setCertificateEntry(String.valueOf(i), certificateFactory.generateCertificate(certificate));
                certificate.close();
            }
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            //  信任该证书证书
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            LogUtil.iYx(e.getMessage());
        }
        return null;
    }


    /**
     * 获取Https的证书
     *
     * @return SSL的上下文对象
     */
    private static SSLContext getSSLContext() {
        SSLContext s_sSLContext;
        try {
            s_sSLContext = SSLContext.getInstance("TLS");

            // 信任所有证书 （官方不推荐使用）
            s_sSLContext.init(null, new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }}, new SecureRandom());

            return s_sSLContext;
        } catch (Exception e) {
            LogUtil.iYx(e.getMessage());
        }
        return null;
    }

    // 双向证书
    public static X509TrustManager getSSLX509TrustManager() {
        try {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:"
                        + Arrays.toString(trustManagers));
            }
            X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
            return trustManager;
            /*
            KeyStore keystore = KeyStore.getInstance("PKCS12");
            char[] keyPassword = tradeNumber.toCharArray();
            // 证书密码
            keystore.load(resource.getInputStream(), keyPassword);
            SSLContext wx_ssl_context = SSLContext.getInstance("TLS");
            KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmfactory.init(keystore, keyPassword);
            wx_ssl_context.init(kmfactory.getKeyManagers(), new TrustManager[]{trustManager}, new SecureRandom());
            SSLSocketFactory sslSocketFactory = wx_ssl_context.getSocketFactory();
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .sslSocketFactory(sslSocketFactory, trustManager).connectionPool(new ConnectionPool(300, 3, TimeUnit.MINUTES)).build();
            */
        } catch (Exception e) {
            //  e.printStackTrace();
        }
        return null;
    }


    // 获取HostnameVerifier
    public static HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        };
        return hostnameVerifier;
    }

    //  获取HostnameVerifier;hostUrls是你的host数据 列如 String hosts[]`= {“https // :aaaa,com”, “https // :bbb.com”}
    public static HostnameVerifier getHostnameVerifier(final String[] hostUrls) {

        HostnameVerifier TRUSTED_VERIFIER = new HostnameVerifier() {

            public boolean verify(String hostname, SSLSession session) {
                boolean ret = false;
                for (String host : hostUrls) {
                    if (host.equalsIgnoreCase(hostname)) {
                        ret = true;
                    }
                }
                return ret;
            }
        };

        return TRUSTED_VERIFIER;
    }

}
